home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / SCUBE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  17.2 KB  |  704 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. /*
  42.  * 1992 David G Yu -- Silicon Graphics Computer Systems
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <math.h>
  49. #include <GL/glut.h>
  50.  
  51. static int useRGB = 1;
  52. static int useLighting = 1;
  53. static int useFog = 0;
  54. static int useDB = 1;
  55. static int useLogo = 0;
  56. static int useQuads = 1;
  57.  
  58. static int tick = -1;
  59. static int moving = 1;
  60.  
  61. #define GREY    0
  62. #define RED    1
  63. #define GREEN    2
  64. #define BLUE    3
  65. #define CYAN    4
  66. #define MAGENTA    5
  67. #define YELLOW    6
  68. #define BLACK    7
  69.  
  70. static float materialColor[8][4] =
  71. {
  72.   {0.8, 0.8, 0.8, 1.0},
  73.   {0.8, 0.0, 0.0, 1.0},
  74.   {0.0, 0.8, 0.0, 1.0},
  75.   {0.0, 0.0, 0.8, 1.0},
  76.   {0.0, 0.8, 0.8, 1.0},
  77.   {0.8, 0.0, 0.8, 1.0},
  78.   {0.8, 0.8, 0.0, 1.0},
  79.   {0.0, 0.0, 0.0, 0.6},
  80. };
  81.  
  82. static float lightPos[4] =
  83. {2.0, 4.0, 2.0, 1.0};
  84. #if 0
  85. static float lightDir[4] =
  86. {-2.0, -4.0, -2.0, 1.0};
  87. #endif
  88. static float lightAmb[4] =
  89. {0.2, 0.2, 0.2, 1.0};
  90. static float lightDiff[4] =
  91. {0.8, 0.8, 0.8, 1.0};
  92. static float lightSpec[4] =
  93. {0.4, 0.4, 0.4, 1.0};
  94.  
  95. static float groundPlane[4] =
  96. {0.0, 1.0, 0.0, 1.499};
  97. static float backPlane[4] =
  98. {0.0, 0.0, 1.0, 0.899};
  99.  
  100. static float fogColor[4] =
  101. {0.0, 0.0, 0.0, 0.0};
  102. static float fogIndex[1] =
  103. {0.0};
  104.  
  105. static unsigned char shadowPattern[128] =
  106. {
  107.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,  /* 50% Grey */
  108.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  109.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  110.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  111.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  112.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  113.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  114.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  115.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  116.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  117.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  118.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  119.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  120.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  121.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  122.   0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
  123. };
  124.  
  125. static unsigned char sgiPattern[128] =
  126. {
  127.   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  /* SGI Logo */
  128.   0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef,
  129.   0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef,
  130.   0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef,
  131.   0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83,
  132.   0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff,
  133.   0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb,
  134.   0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3,
  135.   0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf,
  136.   0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7,
  137.   0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff,
  138.   0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb,
  139.   0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb,
  140.   0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf,
  141.   0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3,
  142.   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  143. };
  144.  
  145. static float cube_vertexes[6][4][4] =
  146. {
  147.   {
  148.     {-1.0, -1.0, -1.0, 1.0},
  149.     {-1.0, -1.0, 1.0, 1.0},
  150.     {-1.0, 1.0, 1.0, 1.0},
  151.     {-1.0, 1.0, -1.0, 1.0}},
  152.  
  153.   {
  154.     {1.0, 1.0, 1.0, 1.0},
  155.     {1.0, -1.0, 1.0, 1.0},
  156.     {1.0, -1.0, -1.0, 1.0},
  157.     {1.0, 1.0, -1.0, 1.0}},
  158.  
  159.   {
  160.     {-1.0, -1.0, -1.0, 1.0},
  161.     {1.0, -1.0, -1.0, 1.0},
  162.     {1.0, -1.0, 1.0, 1.0},
  163.     {-1.0, -1.0, 1.0, 1.0}},
  164.  
  165.   {
  166.     {1.0, 1.0, 1.0, 1.0},
  167.     {1.0, 1.0, -1.0, 1.0},
  168.     {-1.0, 1.0, -1.0, 1.0},
  169.     {-1.0, 1.0, 1.0, 1.0}},
  170.  
  171.   {
  172.     {-1.0, -1.0, -1.0, 1.0},
  173.     {-1.0, 1.0, -1.0, 1.0},
  174.     {1.0, 1.0, -1.0, 1.0},
  175.     {1.0, -1.0, -1.0, 1.0}},
  176.  
  177.   {
  178.     {1.0, 1.0, 1.0, 1.0},
  179.     {-1.0, 1.0, 1.0, 1.0},
  180.     {-1.0, -1.0, 1.0, 1.0},
  181.     {1.0, -1.0, 1.0, 1.0}}
  182. };
  183.  
  184. static float cube_normals[6][4] =
  185. {
  186.   {-1.0, 0.0, 0.0, 0.0},
  187.   {1.0, 0.0, 0.0, 0.0},
  188.   {0.0, -1.0, 0.0, 0.0},
  189.   {0.0, 1.0, 0.0, 0.0},
  190.   {0.0, 0.0, -1.0, 0.0},
  191.   {0.0, 0.0, 1.0, 0.0}
  192. };
  193.  
  194. static void
  195. usage(void)
  196. {
  197.   printf("\n");
  198.   printf("usage: scube [options]\n");
  199.   printf("\n");
  200.   printf("    display a spinning cube and its shadow\n");
  201.   printf("\n");
  202.   printf("  Options:\n");
  203.   printf("    -geometry  window size and location\n");
  204.   printf("    -c         toggle color index mode\n");
  205.   printf("    -l         toggle lighting\n");
  206.   printf("    -f         toggle fog\n");
  207.   printf("    -db        toggle double buffering\n");
  208.   printf("    -logo      toggle sgi logo for the shadow pattern\n");
  209.   printf("    -quads     toggle use of GL_QUADS to draw the checkerboard\n");
  210.   printf("\n");
  211. #ifndef EXIT_FAILURE    /* should be defined by ANSI C
  212.                            <stdlib.h> */
  213. #define EXIT_FAILURE 1
  214. #endif
  215.   exit(EXIT_FAILURE);
  216. }
  217.  
  218. void
  219. buildColormap(void)
  220. {
  221.   if (useRGB) {
  222.     return;
  223.   } else {
  224.     int mapSize = 1 << glutGet(GLUT_WINDOW_BUFFER_SIZE);
  225.     int rampSize = mapSize / 8;
  226.     int entry;
  227.     int i;
  228.  
  229.     for (entry = 0; entry < mapSize; ++entry) {
  230.       int hue = entry / rampSize;
  231.       GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1));
  232.       GLfloat red, green, blue;
  233.  
  234.       red = (hue == 0 || hue == 1 || hue == 5 || hue == 6) ? val : 0;
  235.       green = (hue == 0 || hue == 2 || hue == 4 || hue == 6) ? val : 0;
  236.       blue = (hue == 0 || hue == 3 || hue == 4 || hue == 5) ? val : 0;
  237.  
  238.       glutSetColor(entry, red, green, blue);
  239.     }
  240.  
  241.     for (i = 0; i < 8; ++i) {
  242.       materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1);
  243.       materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1);
  244.       materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1);
  245.       materialColor[i][3] = 0.0;
  246.     }
  247.  
  248.     fogIndex[0] = -0.2 * (rampSize - 1);
  249.   }
  250. }
  251.  
  252. static void
  253. setColor(int c)
  254. {
  255.   if (useLighting) {
  256.     if (useRGB) {
  257.       glMaterialfv(GL_FRONT_AND_BACK,
  258.         GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
  259.     } else {
  260.       glMaterialfv(GL_FRONT_AND_BACK,
  261.         GL_COLOR_INDEXES, &materialColor[c][0]);
  262.     }
  263.   } else {
  264.     if (useRGB) {
  265.       glColor4fv(&materialColor[c][0]);
  266.     } else {
  267.       glIndexf(materialColor[c][1]);
  268.     }
  269.   }
  270. }
  271.  
  272. static void
  273. drawCube(int color)
  274. {
  275.   int i;
  276.  
  277.   setColor(color);
  278.  
  279.   for (i = 0; i < 6; ++i) {
  280.     glNormal3fv(&cube_normals[i][0]);
  281.     glBegin(GL_POLYGON);
  282.     glVertex4fv(&cube_vertexes[i][0][0]);
  283.     glVertex4fv(&cube_vertexes[i][1][0]);
  284.     glVertex4fv(&cube_vertexes[i][2][0]);
  285.     glVertex4fv(&cube_vertexes[i][3][0]);
  286.     glEnd();
  287.   }
  288. }
  289.  
  290. static void
  291. drawCheck(int w, int h, int evenColor, int oddColor)
  292. {
  293.   static int initialized = 0;
  294.   static int usedLighting = 0;
  295.   static GLuint checklist = 0;
  296.  
  297.   if (!initialized || (usedLighting != useLighting)) {
  298.     static float square_normal[4] =
  299.     {0.0, 0.0, 1.0, 0.0};
  300.     static float square[4][4];
  301.     int i, j;
  302.  
  303.     if (!checklist) {
  304.       checklist = glGenLists(1);
  305.     }
  306.     glNewList(checklist, GL_COMPILE_AND_EXECUTE);
  307.  
  308.     if (useQuads) {
  309.       glNormal3fv(square_normal);
  310.       glBegin(GL_QUADS);
  311.     }
  312.     for (j = 0; j < h; ++j) {
  313.       for (i = 0; i < w; ++i) {
  314.         square[0][0] = -1.0 + 2.0 / w * i;
  315.         square[0][1] = -1.0 + 2.0 / h * (j + 1);
  316.         square[0][2] = 0.0;
  317.         square[0][3] = 1.0;
  318.  
  319.         square[1][0] = -1.0 + 2.0 / w * i;
  320.         square[1][1] = -1.0 + 2.0 / h * j;
  321.         square[1][2] = 0.0;
  322.         square[1][3] = 1.0;
  323.  
  324.         square[2][0] = -1.0 + 2.0 / w * (i + 1);
  325.         square[2][1] = -1.0 + 2.0 / h * j;
  326.         square[2][2] = 0.0;
  327.         square[2][3] = 1.0;
  328.  
  329.         square[3][0] = -1.0 + 2.0 / w * (i + 1);
  330.         square[3][1] = -1.0 + 2.0 / h * (j + 1);
  331.         square[3][2] = 0.0;
  332.         square[3][3] = 1.0;
  333.  
  334.         if ((i & 1) ^ (j & 1)) {
  335.           setColor(oddColor);
  336.         } else {
  337.           setColor(evenColor);
  338.         }
  339.  
  340.         if (!useQuads) {
  341.           glBegin(GL_POLYGON);
  342.         }
  343.         glVertex4fv(&square[0][0]);
  344.         glVertex4fv(&square[1][0]);
  345.         glVertex4fv(&square[2][0]);
  346.         glVertex4fv(&square[3][0]);
  347.         if (!useQuads) {
  348.           glEnd();
  349.         }
  350.       }
  351.     }
  352.  
  353.     if (useQuads) {
  354.       glEnd();
  355.     }
  356.     glEndList();
  357.  
  358.     initialized = 1;
  359.     usedLighting = useLighting;
  360.   } else {
  361.     glCallList(checklist);
  362.   }
  363. }
  364.  
  365. static void
  366. myShadowMatrix(float ground[4], float light[4])
  367. {
  368.   float dot;
  369.   float shadowMat[4][4];
  370.  
  371.   dot = ground[0] * light[0] +
  372.     ground[1] * light[1] +
  373.     ground[2] * light[2] +
  374.     ground[3] * light[3];
  375.  
  376.   shadowMat[0][0] = dot - light[0] * ground[0];
  377.   shadowMat[1][0] = 0.0 - light[0] * ground[1];
  378.   shadowMat[2][0] = 0.0 - light[0] * ground[2];
  379.   shadowMat[3][0] = 0.0 - light[0] * ground[3];
  380.  
  381.   shadowMat[0][1] = 0.0 - light[1] * ground[0];
  382.   shadowMat[1][1] = dot - light[1] * ground[1];
  383.   shadowMat[2][1] = 0.0 - light[1] * ground[2];
  384.   shadowMat[3][1] = 0.0 - light[1] * ground[3];
  385.  
  386.   shadowMat[0][2] = 0.0 - light[2] * ground[0];
  387.   shadowMat[1][2] = 0.0 - light[2] * ground[1];
  388.   shadowMat[2][2] = dot - light[2] * ground[2];
  389.   shadowMat[3][2] = 0.0 - light[2] * ground[3];
  390.  
  391.   shadowMat[0][3] = 0.0 - light[3] * ground[0];
  392.   shadowMat[1][3] = 0.0 - light[3] * ground[1];
  393.   shadowMat[2][3] = 0.0 - light[3] * ground[2];
  394.   shadowMat[3][3] = dot - light[3] * ground[3];
  395.  
  396.   glMultMatrixf((const GLfloat *) shadowMat);
  397. }
  398.  
  399. static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)";
  400. static char *windowNameRGB = "shadow cube (OpenGL RGB)";
  401. static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)";
  402. static char *windowNameIndex = "shadow cube (OpenGL Index)";
  403.  
  404. void
  405. idle(void)
  406. {
  407.   tick++;
  408.   if (tick >= 120) {
  409.     tick = 0;
  410.   }
  411.   glutPostRedisplay();
  412. }
  413.  
  414. /* ARGSUSED1 */
  415. void
  416. keyboard(unsigned char ch, int x, int y)
  417. {
  418.   switch (ch) {
  419.   case 27:             /* escape */
  420.     exit(0);
  421.     break;
  422.   case 'L':
  423.   case 'l':
  424.     useLighting = !useLighting;
  425.     useLighting ? glEnable(GL_LIGHTING) :
  426.       glDisable(GL_LIGHTING);
  427.     glutPostRedisplay();
  428.     break;
  429.   case 'F':
  430.   case 'f':
  431.     useFog = !useFog;
  432.     useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  433.     glutPostRedisplay();
  434.     break;
  435.   case '1':
  436.     glFogf(GL_FOG_MODE, GL_LINEAR);
  437.     glutPostRedisplay();
  438.     break;
  439.   case '2':
  440.     glFogf(GL_FOG_MODE, GL_EXP);
  441.     glutPostRedisplay();
  442.     break;
  443.   case '3':
  444.     glFogf(GL_FOG_MODE, GL_EXP2);
  445.     glutPostRedisplay();
  446.     break;
  447.   case ' ':
  448.     if (!moving) {
  449.       idle();
  450.       glutPostRedisplay();
  451.     }
  452.   }
  453. }
  454.  
  455. void
  456. display(void)
  457. {
  458.   GLfloat cubeXform[4][4];
  459.  
  460.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  461.  
  462.   glPushMatrix();
  463.   glTranslatef(0.0, -1.5, 0.0);
  464.   glRotatef(-90.0, 1, 0, 0);
  465.   glScalef(2.0, 2.0, 2.0);
  466.  
  467.   drawCheck(6, 6, BLUE, YELLOW);  /* draw ground */
  468.   glPopMatrix();
  469.  
  470.   glPushMatrix();
  471.   glTranslatef(0.0, 0.0, -0.9);
  472.   glScalef(2.0, 2.0, 2.0);
  473.  
  474.   drawCheck(6, 6, BLUE, YELLOW);  /* draw back */
  475.   glPopMatrix();
  476.  
  477.   glPushMatrix();
  478.   glTranslatef(0.0, 0.2, 0.0);
  479.   glScalef(0.3, 0.3, 0.3);
  480.   glRotatef((360.0 / (30 * 1)) * tick, 1, 0, 0);
  481.   glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0);
  482.   glRotatef((360.0 / (30 * 4)) * tick, 0, 0, 1);
  483.   glScalef(1.0, 2.0, 1.0);
  484.   glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform);
  485.  
  486.   drawCube(RED);        /* draw cube */
  487.   glPopMatrix();
  488.  
  489.   glDepthMask(GL_FALSE);
  490.   if (useRGB) {
  491.     glEnable(GL_BLEND);
  492.   } else {
  493.     glEnable(GL_POLYGON_STIPPLE);
  494.   }
  495.   if (useFog) {
  496.     glDisable(GL_FOG);
  497.   }
  498.   glPushMatrix();
  499.   myShadowMatrix(groundPlane, lightPos);
  500.   glTranslatef(0.0, 0.0, 2.0);
  501.   glMultMatrixf((const GLfloat *) cubeXform);
  502.  
  503.   drawCube(BLACK);      /* draw ground shadow */
  504.   glPopMatrix();
  505.  
  506.   glPushMatrix();
  507.   myShadowMatrix(backPlane, lightPos);
  508.   glTranslatef(0.0, 0.0, 2.0);
  509.   glMultMatrixf((const GLfloat *) cubeXform);
  510.  
  511.   drawCube(BLACK);      /* draw back shadow */
  512.   glPopMatrix();
  513.  
  514.   glDepthMask(GL_TRUE);
  515.   if (useRGB) {
  516.     glDisable(GL_BLEND);
  517.   } else {
  518.     glDisable(GL_POLYGON_STIPPLE);
  519.   }
  520.   if (useFog) {
  521.     glEnable(GL_FOG);
  522.   }
  523.   if (useDB) {
  524.     glutSwapBuffers();
  525.   } else {
  526.     glFlush();
  527.   }
  528. }
  529.  
  530. void
  531. fog_select(int fog)
  532. {
  533.   glFogf(GL_FOG_MODE, fog);
  534.   glutPostRedisplay();
  535. }
  536.  
  537. void
  538. menu_select(int mode)
  539. {
  540.   switch (mode) {
  541.   case 1:
  542.     moving = 1;
  543.     glutIdleFunc(idle);
  544.     break;
  545.   case 2:
  546.     moving = 0;
  547.     glutIdleFunc(NULL);
  548.     break;
  549.   case 3:
  550.     useFog = !useFog;
  551.     useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  552.     glutPostRedisplay();
  553.     break;
  554.   case 4:
  555.     useLighting = !useLighting;
  556.     useLighting ? glEnable(GL_LIGHTING) :
  557.       glDisable(GL_LIGHTING);
  558.     glutPostRedisplay();
  559.     break;
  560.   case 5:
  561.     exit(0);
  562.     break;
  563.   }
  564. }
  565.  
  566. void
  567. visible(int state)
  568. {
  569.   if (state == GLUT_VISIBLE) {
  570.     if (moving)
  571.       glutIdleFunc(idle);
  572.   } else {
  573.     if (moving)
  574.       glutIdleFunc(NULL);
  575.   }
  576. }
  577.  
  578. int
  579. main(int argc, char **argv)
  580. {
  581.   int width = 350, height = 350;
  582.   int i;
  583.   char *name;
  584.   int fog_menu;
  585.  
  586.   glutInitWindowSize(width, height);
  587.   glutInit(&argc, argv);
  588.   /* process commmand line args */
  589.   for (i = 1; i < argc; ++i) {
  590.     if (!strcmp("-c", argv[i])) {
  591.       useRGB = !useRGB;
  592.     } else if (!strcmp("-l", argv[i])) {
  593.       useLighting = !useLighting;
  594.     } else if (!strcmp("-f", argv[i])) {
  595.       useFog = !useFog;
  596.     } else if (!strcmp("-db", argv[i])) {
  597.       useDB = !useDB;
  598.     } else if (!strcmp("-logo", argv[i])) {
  599.       useLogo = !useLogo;
  600.     } else if (!strcmp("-quads", argv[i])) {
  601.       useQuads = !useQuads;
  602.     } else {
  603.       usage();
  604.     }
  605.   }
  606.  
  607.   /* choose visual */
  608.   if (useRGB) {
  609.     if (useDB) {
  610.       glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  611.       name = windowNameRGBDB;
  612.     } else {
  613.       glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
  614.       name = windowNameRGB;
  615.     }
  616.   } else {
  617.     if (useDB) {
  618.       glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH);
  619.       name = windowNameIndexDB;
  620.     } else {
  621.       glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH);
  622.       name = windowNameIndex;
  623.     }
  624.   }
  625.  
  626.   glutCreateWindow(name);
  627.  
  628.   buildColormap();
  629.  
  630.   glutKeyboardFunc(keyboard);
  631.   glutDisplayFunc(display);
  632.   glutVisibilityFunc(visible);
  633.  
  634.   fog_menu = glutCreateMenu(fog_select);
  635.   glutAddMenuEntry("Linear fog", GL_LINEAR);
  636.   glutAddMenuEntry("Exp fog", GL_EXP);
  637.   glutAddMenuEntry("Exp^2 fog", GL_EXP2);
  638.  
  639.   glutCreateMenu(menu_select);
  640.   glutAddMenuEntry("Start motion", 1);
  641.   glutAddMenuEntry("Stop motion", 2);
  642.   glutAddMenuEntry("Toggle fog", 3);
  643.   glutAddMenuEntry("Toggle lighting", 4);
  644.   glutAddSubMenu("Fog type", fog_menu);
  645.   glutAddMenuEntry("Quit", 5);
  646.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  647.  
  648.   /* setup context */
  649.   glMatrixMode(GL_PROJECTION);
  650.   glLoadIdentity();
  651.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
  652.  
  653.   glMatrixMode(GL_MODELVIEW);
  654.   glLoadIdentity();
  655.   glTranslatef(0.0, 0.0, -2.0);
  656.  
  657.   glEnable(GL_DEPTH_TEST);
  658.  
  659.   if (useLighting) {
  660.     glEnable(GL_LIGHTING);
  661.   }
  662.   glEnable(GL_LIGHT0);
  663.   glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  664.   glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  665.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  666.   glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  667. #if 0
  668.   glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
  669.   glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
  670.   glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
  671. #endif
  672.  
  673.   glEnable(GL_NORMALIZE);
  674.  
  675.   if (useFog) {
  676.     glEnable(GL_FOG);
  677.   }
  678.   glFogfv(GL_FOG_COLOR, fogColor);
  679.   glFogfv(GL_FOG_INDEX, fogIndex);
  680.   glFogf(GL_FOG_MODE, GL_EXP);
  681.   glFogf(GL_FOG_DENSITY, 0.5);
  682.   glFogf(GL_FOG_START, 1.0);
  683.   glFogf(GL_FOG_END, 3.0);
  684.  
  685.   glEnable(GL_CULL_FACE);
  686.   glCullFace(GL_BACK);
  687.  
  688.   glShadeModel(GL_SMOOTH);
  689.  
  690.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  691.   if (useLogo) {
  692.     glPolygonStipple((const GLubyte *) sgiPattern);
  693.   } else {
  694.     glPolygonStipple((const GLubyte *) shadowPattern);
  695.   }
  696.  
  697.   glClearColor(0.0, 0.0, 0.0, 1);
  698.   glClearIndex(0);
  699.   glClearDepth(1);
  700.  
  701.   glutMainLoop();
  702.   return 0;             /* ANSI C requires main to return int. */
  703. }
  704.